package de.codi.mappingevaluation;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import de.unima.alcomox.mapping.Correspondence;

public class CorrespondencePlus implements Comparable<CorrespondencePlus> {
	private Correspondence c;
	private List<String> sourceDesc;
	private List<String> targetDesc;
	private boolean correct;
	private boolean clear;
	private int count;
	private String id;

	public CorrespondencePlus(Correspondence c, Set<String> source, Set<String> target, boolean correct) {
		this.c = c;
		this.correct = correct;
		this.id = c.getSourceEntityId()+"_"+ c.getTargetEntityId();
		this.sourceDesc = new ArrayList<String>(source);
		Collections.sort(sourceDesc);
		this.targetDesc = new ArrayList<String>(target);
		Collections.sort(targetDesc);
		clear = checkWordSet();
		count = 0;
	}
	

	public List<String> getSourceDesc() {
		return sourceDesc;
	}

	public List<String> getTargetDesc() {
		return targetDesc;
	}
	
	public String getSourceID() {
		return c.getSourceEntityId();
	}
	public String getTargetID() {
		return c.getTargetEntityId();
	}
	
	public String getSourceUri() {
		return c.getSourceEntityUri();
	}
	public String getTargetUri() {
		return c.getTargetEntityUri();
	}
	public void incCount(){
		count++;
	}
	
	public String getID(){
		return id;
	}
	
	public int getCount(){
		return count;
	}

	public boolean isCorrect(){
		return correct;
	}
	
	public String getHTML(String info){
		String htmlClass;
		if (correct){
			htmlClass = "correct";
		} else {
			htmlClass = "wrong";
		}
		
		String clearClass;
		if (clear){
			clearClass = " class=\"clear\" ";
		} else{
			clearClass = "";
		}
		
		String top = "&#09;" + "<a href=\"#head\">" + "[top]" + "</a>";
		String s = "";
		s += "<div id=" + id + ">";
		s += "<h2 class=\""+ htmlClass + "\">"+ id + top + "</h2>";
		s+=	"<table class=\"mapping\"><tr><th>";
		s+= getSourceUri() + "</th><th>" + getTargetUri() + "</th></tr>";
		s+= "<tr"+ clearClass +"><td>";
		s+= getHTMLList(sourceDesc);
		s+="</td><td>";
		s+= getHTMLList(targetDesc);
		s+= "</td></tr>"; 
		s+= "</table>";
		s+= "<p class=\"setting\">" +info + "</p>";
		s += "</div>";
		return s;
	}
	
	private String getHTMLList(List<String> l){
		String s ="<ul>";
		for (String e : l){
			s+="<li>" + e + "</li>";
		}
		s+="</ul>";
		return s;
	}
	
	@Override
	public int compareTo(CorrespondencePlus cp) {
		if (this.correct == true && cp.correct == false) {
			return -1;
		} else if (this.correct == false && cp.correct == true) {
			return 1;
		} else if (this.count > cp.count) {
			return -1;
		} else if (this.count < cp.count) {
			return 1;
		} else if (this.clear == true && cp.clear == false) {
			return -1;
		} else if (this.clear == false && cp.clear == true) {
			return 1;
		} else {
			return this.c.compareTo(cp.c);
		}
	}
	
	private boolean checkWordSet(){
		for (String source : sourceDesc){
			for (String target : targetDesc){
				if (getSim(source, target)== 1.0){
					return true;					
				}
			}
		}
		return false;
	}
	
	public double getSim(String a, String b) {
		
		if (a.equals(b)){
			return 1.0;
		}
		
		Set<String> aS = getWords(a);
		Set<String> bS = getWords(b);
		int n=0;
		for (String s : aS){
			if (bS.contains(s)){
				n++;
			}
		}
		
		if (n == bS.size() && n == aS.size()){
			return 1.0;
		}
		
		if((n == aS.size() || n == bS.size()) && ((float) (Math.min(aS.size(), bS.size())) / Math.max(aS.size(), bS.size())) > 0.70){
			return 1.0;
		}
		
		return 0.0;
	}	
	
	private Set<String> getWords(String s){
		String[] temp = s.split(" ");
		Set<String> set = new HashSet<String>();
		for (int i=0; i<temp.length; i++){
			set.add(temp[i]);
		}
		return set;
	}


	public boolean isClear() {
		return clear;
	}	
}
